package com.study.choosemaster;


import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created By gtx on 2017/8/11/19:47
 */
public class MasterSelector {
    /**选举时争抢的节点*/
    private static final String MASTER_PATH="/master";
    private ZkClient zkClient;
    /**监听节点数据变化*/
    private IZkDataListener iZkDataListener;
    /**当前选举是否在进行*/
    private boolean isRunning=false;

    private UserCenter server;

    private UserCenter master;

    private ScheduledExecutorService scheduledExecutorService= Executors.newScheduledThreadPool(1);

    public MasterSelector(UserCenter server) {
        this.server=server;
        this.zkClient = ZkClientFactory.getInstance();
        this.iZkDataListener = new IZkDataListener() {
            public void handleDataChange(String dataPath, Object data) throws Exception {

            }

            public void handleDataDeleted(String dataPath) throws Exception {
                //master挂掉后重新选举
                chooseMaster();
            }
        };
    }

    /**
     * 具体的选举实现
     */
    private void chooseMaster(){
        System.out.println(server.getMc_name()+"去争抢master权限");
        try {
            isRunning = true;
            zkClient.createEphemeral(MASTER_PATH,server);
            //走到这里代表创建节点成功，当前的server就是master
            master=server;
            System.out.println(master.getMc_name()+"->已经被选举为master");

            //模拟master挂掉
            scheduledExecutorService.schedule(new Runnable() {
                public void run() {
                    System.out.println(master.getMc_name()+"->已经被删除");
                    stop();
                }
            },10,TimeUnit.SECONDS);
        } catch (RuntimeException e) {
            //创建失败后再检测一次
            try {
                TimeUnit.MILLISECONDS.sleep(200);
                UserCenter data = zkClient.readData(MASTER_PATH,true);
                if (data == null) {
                    //未获取到节点数据，代表master可能挂掉，可以重新选举
                    chooseMaster();
                }
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }


    }

    /**
     * 开始方法：调用此方法后开始选举
     */
    public void start(){
       if (isRunning)return;
       chooseMaster();
    }

    /**
     * 结束方法：调用此方法后选举结束
     */
    public void stop(){
        if (!isMaster())return;
        if (!isRunning)return;
        try {
            isRunning=false;
            scheduledExecutorService.shutdown();
            zkClient.unsubscribeDataChanges(MASTER_PATH,iZkDataListener);

            zkClient.delete(MASTER_PATH);

        } catch (Exception e) {
            System.err.println("服务停止失败...");
            e.printStackTrace();
        }

    }

    private boolean isMaster(){
        return server.equals(master);
    }





}
